﻿//--------------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2012 , gt TECH, Ltd.
//--------------------------------------------------------------------

using System;
using System.Data;

namespace RDIFramework.ServiceAdapter
{
    using RDIFramework.BusinessEntity;
    using RDIFramework.Utilities;
    using System.Collections.Generic;

 /// <summary>
 /// PiUserManager
 /// 用户账户表
 ///
 /// 修改纪录
 ///
 ///		2012-03-02 版本：1.0 EricHu 创建主键。
 ///
 /// 版本：1.0
 ///
 /// <author>
 ///		<name>EricHu</name>
 ///		<date>2012-03-02</date>
 /// </author>
 /// </summary>
    public partial class PiUserManager : DbCommonManager,IDbCommonManager
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public PiUserManager()
        {
            if (base.dbProvider == null)
            {
                base.dbProvider = DbFactoryProvider.GetProvider(SystemInfo.RDIFrameworkDbType, SystemInfo.RDIFrameworkDbConection);
            }
            base.CurrentTableName = PiUserTable.TableName;
        }

        /// <summary>
        /// 构造函数
        /// <param name="tableName">指定表名</param>
        /// </summary>
        public PiUserManager(string tableName)
        {
            base.CurrentTableName = tableName;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbProvider">数据库连接</param>
        public PiUserManager(IDbProvider dbProvider)
            : this()
        {
            DBProvider = dbProvider;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        public PiUserManager(UserInfo userInfo)
            : this()
        {
            UserInfo = userInfo;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbProvider">数据库连接</param>
        /// <param name="userInfo">用户信息</param>
        public PiUserManager(IDbProvider dbProvider, UserInfo userInfo)
            : this(dbProvider)
        {
            UserInfo = userInfo;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dbProvider">数据库连接</param>
        /// <param name="userInfo">用户信息</param>
        /// <param name="tableName">指定表名</param>
        public PiUserManager(IDbProvider dbProvider, UserInfo userInfo, string tableName)
            : this(dbProvider, userInfo)
        {
            base.CurrentTableName = tableName;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        /// <returns>主键</returns>
        public string Add(PiUserEntity baseUserEntity)
        {
            return this.AddEntity(baseUserEntity);
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        /// <param name="identity">自增量方式</param>
        /// <param name="returnId">返回主鍵</param>
        /// <returns>主键</returns>
        public string Add(PiUserEntity baseUserEntity, bool identity, bool returnId)
        {
            this.Identity = identity;
            this.ReturnId = returnId;
            return this.AddEntity(baseUserEntity);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        public int Update(PiUserEntity baseUserEntity)
        {
            return this.UpdateEntity(baseUserEntity);
        }

        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id">主键</param>
        public PiUserEntity GetEntity(int? id)
        {
            PiUserEntity baseUserEntity = new PiUserEntity(this.GetDT(PiUserTable.FieldId, id));
            return baseUserEntity;
        }

        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id">主键</param>
        public PiUserEntity GetEntity(string id)
        {
            PiUserEntity baseUserEntity = new PiUserEntity(this.GetDT(PiUserTable.FieldId, id));
            return baseUserEntity;
        }

        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        public string AddEntity(PiUserEntity userEntity)
        {
            string sequence = string.Empty;
            if (userEntity.SortCode == 0 || userEntity.SortCode == null)
            {
                CiSequenceManager sequenceManager = new CiSequenceManager(DBProvider, this.Identity);
                sequence = sequenceManager.GetSequence(this.CurrentTableName);
                userEntity.SortCode = int.Parse(sequence);
            }
            SQLBuilder sqlBuilder = new SQLBuilder(DBProvider, this.Identity, this.ReturnId);
            sqlBuilder.BeginInsert(this.CurrentTableName, PiUserTable.FieldId);
            if (!this.Identity)
            {
                sqlBuilder.SetValue(PiUserTable.FieldId, userEntity.Id);
            }
            else
            {
                if (!this.ReturnId && (DBProvider.CurrentDbType == CurrentDbType.Oracle || DBProvider.CurrentDbType == CurrentDbType.DB2))
                {
                    if (DBProvider.CurrentDbType == CurrentDbType.Oracle)
                    {
                        sqlBuilder.SetFormula(PiUserTable.FieldId, "SEQ_" + this.CurrentTableName.ToUpper() + ".NEXTVAL ");
                    }
                    if (DBProvider.CurrentDbType == CurrentDbType.DB2)
                    {
                        sqlBuilder.SetFormula(PiUserTable.FieldId, "NEXT VALUE FOR SEQ_" + this.CurrentTableName.ToUpper());
                    }
                }
                else
                {
                    if (this.Identity && (DBProvider.CurrentDbType == CurrentDbType.Oracle || DBProvider.CurrentDbType == CurrentDbType.DB2))
                    {
                        if (userEntity.Id == null)
                        {
                            if (string.IsNullOrEmpty(sequence))
                            {
                                CiSequenceManager sequenceManager = new CiSequenceManager(DBProvider, this.Identity);
                                sequence = sequenceManager.GetSequence(this.CurrentTableName);
                            }
                            userEntity.Id = int.Parse(sequence);
                        }
                        sqlBuilder.SetValue(PiUserTable.FieldId, userEntity.Id);
                    }
                }
            }
            this.SetEntity(sqlBuilder, userEntity);
            if (UserInfo != null)
            {
                sqlBuilder.SetValue(PiUserTable.FieldCreateUserId, UserInfo.Id);
                sqlBuilder.SetValue(PiUserTable.FieldCreateBy, UserInfo.RealName);
            }
            sqlBuilder.SetDBNow(PiUserTable.FieldCreateOn);
            if (UserInfo != null)
            {
                sqlBuilder.SetValue(PiUserTable.FieldModifyUserId, UserInfo.Id);
                sqlBuilder.SetValue(PiUserTable.FieldModifiedBy, UserInfo.RealName);
            }
            sqlBuilder.SetDBNow(PiUserTable.FieldModifiedOn);
            if (DBProvider.CurrentDbType == CurrentDbType.SqlServer && this.Identity)
            {
                sequence = sqlBuilder.EndInsert().ToString();
            }
            else
            {
                sqlBuilder.EndInsert();
            }
            return sequence;
        }

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        public int UpdateEntity(PiUserEntity baseUserEntity)
        {
            SQLBuilder sqlBuilder = new SQLBuilder(DBProvider);
            sqlBuilder.BeginUpdate(this.CurrentTableName);
            this.SetEntity(sqlBuilder, baseUserEntity);
            if (UserInfo != null)
            {
                sqlBuilder.SetValue(PiUserTable.FieldModifyUserId, UserInfo.Id);
                sqlBuilder.SetValue(PiUserTable.FieldModifiedBy, UserInfo.RealName);
            }
            sqlBuilder.SetDBNow(PiUserTable.FieldModifiedOn);
            sqlBuilder.SetWhere(PiUserTable.FieldId, baseUserEntity.Id);
            return sqlBuilder.EndUpdate();
        }

        /// <summary>
        /// 设置实体
        /// </summary>
        /// <param name="baseUserEntity">实体</param>
        private void SetEntity(SQLBuilder sqlBuilder, PiUserEntity baseUserEntity)
        {
            sqlBuilder.SetValue(PiUserTable.FieldCode, baseUserEntity.Code);
            sqlBuilder.SetValue(PiUserTable.FieldUserName, baseUserEntity.UserName);
            sqlBuilder.SetValue(PiUserTable.FieldRealName, baseUserEntity.RealName);
            sqlBuilder.SetValue(PiUserTable.FieldRoleId, baseUserEntity.RoleId);
           // sqlBuilder.SetValue(PiUserTable.FieldSecurityLevel, baseUserEntity.SecurityLevel);
            sqlBuilder.SetValue(PiUserTable.FieldUserFrom, baseUserEntity.UserFrom);
            sqlBuilder.SetValue(PiUserTable.FieldWorkCategory, baseUserEntity.WorkCategory);
            sqlBuilder.SetValue(PiUserTable.FieldCompanyId, baseUserEntity.CompanyId);
            sqlBuilder.SetValue(PiUserTable.FieldCompanyName, baseUserEntity.CompanyName);
            sqlBuilder.SetValue(PiUserTable.FieldDepartmentId, baseUserEntity.DepartmentId);
            sqlBuilder.SetValue(PiUserTable.FieldDepartmentName, baseUserEntity.DepartmentName);
            sqlBuilder.SetValue(PiUserTable.FieldWorkgroupId, baseUserEntity.WorkgroupId);
            sqlBuilder.SetValue(PiUserTable.FieldWorkgroupName, baseUserEntity.WorkgroupName);
            sqlBuilder.SetValue(PiUserTable.FieldGender, baseUserEntity.Gender);
            sqlBuilder.SetValue(PiUserTable.FieldMobile, baseUserEntity.Mobile);
            sqlBuilder.SetValue(PiUserTable.FieldTelephone, baseUserEntity.Telephone);
            sqlBuilder.SetValue(PiUserTable.FieldBirthday, baseUserEntity.Birthday);
            sqlBuilder.SetValue(PiUserTable.FieldDuty, baseUserEntity.Duty);
            sqlBuilder.SetValue(PiUserTable.FieldTitle, baseUserEntity.Title);
            sqlBuilder.SetValue(PiUserTable.FieldUserPassword, baseUserEntity.UserPassword);
           // sqlBuilder.SetValue(PiUserTable.FieldCommunicationPassword, baseUserEntity.CommunicationPassword);
            sqlBuilder.SetValue(PiUserTable.FieldQICQ, baseUserEntity.QICQ);
            sqlBuilder.SetValue(PiUserTable.FieldEmail, baseUserEntity.Email);
            sqlBuilder.SetValue(PiUserTable.FieldLang, baseUserEntity.Lang);
            sqlBuilder.SetValue(PiUserTable.FieldTheme, baseUserEntity.Theme);

            sqlBuilder.SetValue(PiUserTable.FieldAllowStartTime, baseUserEntity.AllowStartTime);
            sqlBuilder.SetValue(PiUserTable.FieldAllowEndTime, baseUserEntity.AllowEndTime);
            sqlBuilder.SetValue(PiUserTable.FieldLockStartDate, baseUserEntity.LockStartDate);
            sqlBuilder.SetValue(PiUserTable.FieldLockEndDate, baseUserEntity.LockEndDate);

            sqlBuilder.SetValue(PiUserTable.FieldFirstVisit, baseUserEntity.FirstVisit);
            sqlBuilder.SetValue(PiUserTable.FieldPreviousVisit, baseUserEntity.PreviousVisit);
            sqlBuilder.SetValue(PiUserTable.FieldLastVisit, baseUserEntity.LastVisit);
            sqlBuilder.SetValue(PiUserTable.FieldLogOnCount, baseUserEntity.LogOnCount);
            sqlBuilder.SetValue(PiUserTable.FieldIsStaff, baseUserEntity.IsStaff);
            sqlBuilder.SetValue(PiUserTable.FieldAuditStatus, baseUserEntity.AuditStatus);
            sqlBuilder.SetValue(PiUserTable.FieldIsVisible, baseUserEntity.IsVisible);
            sqlBuilder.SetValue(PiUserTable.FieldUserOnLine, baseUserEntity.UserOnLine);
            sqlBuilder.SetValue(PiUserTable.FieldIPAddress, baseUserEntity.IPAddress);
            sqlBuilder.SetValue(PiUserTable.FieldMACAddress, baseUserEntity.MACAddress);
            sqlBuilder.SetValue(PiUserTable.FieldOpenId, baseUserEntity.OpenId);
            sqlBuilder.SetValue(PiUserTable.FieldQuestion, baseUserEntity.Question);
            sqlBuilder.SetValue(PiUserTable.FieldAnswerQuestion, baseUserEntity.AnswerQuestion);
           //sqlBuilder.SetValue(PiUserTable.FieldUserAddressId, baseUserEntity.UserAddressId);
            sqlBuilder.SetValue(PiUserTable.FieldDeleteMark, baseUserEntity.DeleteMark);
            sqlBuilder.SetValue(PiUserTable.FieldEnabled, baseUserEntity.Enabled);
            sqlBuilder.SetValue(PiUserTable.FieldSortCode, baseUserEntity.SortCode);
            sqlBuilder.SetValue(PiUserTable.FieldDescription, baseUserEntity.Description);
        }

        /// <summary>
        /// 删除实体
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>影响行数</returns>
        public int Delete(int id)
        {            
            return this.Delete(PiUserTable.FieldId, id);            
        }      

        public UserInfo ConvertToUserInfo(PiUserEntity userEntity)
        {
            UserInfo userInfo = new UserInfo();
            return ConvertToUserInfo(userEntity, userInfo);
        }

        public UserInfo ConvertToUserInfo(PiUserEntity userEntity, UserInfo userInfo)
        {
            userInfo.OpenId = userEntity.OpenId;
            userInfo.Id = userEntity.Id.ToString();
            userInfo.Code = userEntity.Code;
            userInfo.UserName = userEntity.UserName;
            userInfo.RealName = userEntity.RealName;
            userInfo.RoleId = userEntity.RoleId;
            userInfo.CompanyId = userEntity.CompanyId;
            userInfo.CompanyName = userEntity.CompanyName;
            userInfo.DepartmentId = userEntity.DepartmentId;
            userInfo.DepartmentName = userEntity.DepartmentName;
            userInfo.WorkgroupId = userEntity.WorkgroupId;
            userInfo.WorkgroupName = userEntity.WorkgroupName;
            //if (userEntity.SecurityLevel == null)
            //{
            //    userEntity.SecurityLevel = 0;
            //}
            //userInfo.SecurityLevel = (int)userEntity.SecurityLevel;
            if (userEntity.RoleId != null)
            {
                // 获取角色名称
                PiRoleManager roleManager = new PiRoleManager(DBProvider, UserInfo);
                PiRoleEntity roleEntity = roleManager.GetEntity(userEntity.RoleId.ToString());
                if (roleEntity.Id > 0)
                {
                    userInfo.RoleName = roleEntity.RealName;
                }
            }
            return userInfo;
        }

        /// <summary>
        /// 判断用户是否已经登录了？
        /// </summary>
        /// <param name="userInfo">用户</param>
        /// <returns>是否已经登录了</returns>
        public bool UserIsLogOn(UserInfo userInfo)
        {
            string[] names = new string[] { PiUserTable.FieldId, PiUserTable.FieldDeleteMark, PiUserTable.FieldEnabled, PiUserTable.FieldOpenId };
            Object[] values = new Object[] { userInfo.Id, 0, 1, userInfo.OpenId };
            string id = this.GetId(names, values);
            if (string.IsNullOrEmpty(id))
            {
                return false;
            }
            if (!userInfo.Id.Equals(id))
            {
                return false;
            }
            return true;
        }

        public bool IsAdministrator(string userId)
        {
            // 用户是超级管理员
            if (userId.Equals("Administrator"))
            {
                return true;
            }
            PiUserEntity userEntity = this.GetEntity(userId);
            if (userEntity.Code != null && userEntity.Code.Equals("Administrator"))
            {
                return true;
            }
            if (userEntity.UserName != null && userEntity.UserName.Equals("Administrator"))
            {
                return true;
            }

            // 用户的默认角色是超级管理员
            PiRoleManager roleManager = new PiRoleManager(this.DBProvider, this.UserInfo);
            // 用户默认角色是否为超级管理员
            PiRoleEntity roleEntity = null;
            if (userEntity.RoleId != null)
            {
                roleEntity = roleManager.GetEntity(userEntity.RoleId.ToString());
                if (roleEntity.Code != null && roleEntity.Code.Equals(DefaultRole.Administrators.ToString()))
                {
                    return true;
                }
            }

            // 用户在超级管理员群里
            PiUserRoleManager userRoleManager = new PiUserRoleManager(this.DBProvider, this.UserInfo);
            string[] roleIds = userRoleManager.GetAllRoleIds(userId);
            for (int i = 0; i < roleIds.Length; i++)
            {
                if (roleIds[i].Equals(DefaultRole.Administrators.ToString()))
                {
                    return true;
                }
                roleEntity = roleManager.GetEntity(roleIds[i]);
                if (roleEntity.Code != null && roleEntity.Code.Equals(DefaultRole.Administrators.ToString()))
                {
                    return true;
                }
            }
            return false;
        }

        #region public DataTable GetDTByDepartment(string departmentId)
        /// <summary>
        /// 按部门获取部门用户
        /// </summary>
        /// <param name="departmentId">部门主键</param>
        /// <returns>数据表</returns>
        public DataTable GetDTByDepartment(string departmentId)
        {
            string sqlQuery = " SELECT " + PiUserTable.TableName + ".* "
                // + " ,(SELECT " + PiOrganizeTable.FieldCode + " FROM " + PiOrganizeTable.TableName + " WHERE Id = " + PiUserTable.TableName + ".CompanyId) AS CompanyCode"
                // + " ,(SELECT " + PiOrganizeTable.FieldFullName + " FROM " + PiOrganizeTable.TableName + " WHERE Id = " + PiUserTable.TableName + ".CompanyId) AS CompanyFullname "
                // + " ,(SELECT " + PiOrganizeTable.FieldCode + " From " + PiOrganizeTable.TableName + " WHERE Id = " + PiUserTable.TableName + ".DepartmentId) AS DepartmentCode"
                // + " ,(SELECT " + PiOrganizeTable.FieldFullName + " FROM " + PiOrganizeTable.TableName + " WHERE Id = " + PiUserTable.TableName + ".DepartmentId) AS DepartmentName "
                // + " ,(SELECT " + PiOrganizeTable.FieldRealName + " FROM " + PiOrganizeTable.TableName + " WHERE Id = RoleId) AS RoleName "
                + " FROM " + PiUserTable.TableName;

            sqlQuery += " WHERE (" + PiUserTable.TableName + "." + PiUserTable.FieldDeleteMark + " = 0 ";
            sqlQuery += " AND " + PiUserTable.TableName + "." + PiUserTable.FieldEnabled + " = 1 ) ";

            if (!String.IsNullOrEmpty(departmentId))
            {
                // 从用户表
                sqlQuery += " AND ((" + PiUserTable.TableName + "." + PiUserTable.FieldDepartmentId + " = '" + departmentId + "') ";
                // 从兼职表读取用户 
                sqlQuery += " OR " + PiUserTable.FieldId + " IN ("
                        + " SELECT " + PiUserOrganizeTable.FieldUserId
                        + "   FROM " + PiUserOrganizeTable.TableName
                        + "  WHERE (" + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldDeleteMark + " = 0 ) "
                        + "       AND (" + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldDepartmentId + " = '" + departmentId + "'))) ";

            }
            sqlQuery += " ORDER BY " + PiUserTable.TableName + "." + PiUserTable.FieldSortCode;
            return DBProvider.Fill(sqlQuery);
        }
        #endregion

        #region public DataTable GetDTByOrganizes(string[] organizeIds) 按工作组、部门、公司获用户列表
        /// <summary>
        /// 按工作组、部门、公司获用户列表
        /// </summary>
        /// <param name="organizeIds">主键数组</param>
        /// <returns>数据表</returns>
        public DataTable GetDTByOrganizes(string[] organizeIds)
        {
            string organizeList = BusinessLogic.ObjectsToList(organizeIds);
            string sqlQuery = " SELECT .* "
                + " FROM " + PiUserTable.TableName
                // 从用户表里去找
                + " WHERE (" + PiUserTable.TableName + "." + PiUserTable.FieldDeleteMark + " = 0 ) "
                + "       AND (" + PiUserTable.TableName + "." + PiUserTable.FieldWorkgroupId + " IN ( " + organizeList + ") "
                + "       OR " + PiUserTable.TableName + "." + PiUserTable.FieldDepartmentId + " IN (" + organizeList + ") "
                + "       OR " + PiUserTable.TableName + "." + PiUserTable.FieldCompanyId + " IN (" + organizeList + ")) "
                // 从用户兼职表里去取用户
                + " OR " + PiUserTable.FieldId + " IN ("
                        + " SELECT " + PiUserOrganizeTable.FieldUserId
                        + "   FROM " + PiUserOrganizeTable.TableName
                        + "  WHERE (" + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldDeleteMark + " = 0 ) "
                        + "       AND (" + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldWorkgroupId + " IN ( " + organizeList + ") "
                        + "       OR " + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldDepartmentId + " IN (" + organizeList + ") "
                        + "       OR " + PiUserOrganizeTable.TableName + "." + PiUserOrganizeTable.FieldCompanyId + " IN (" + organizeList + "))) "
                + " ORDER BY " + PiUserTable.TableName + "." + PiUserTable.FieldSortCode;
            return DBProvider.Fill(sqlQuery);
        }
        #endregion

        #region public UserInfo AccountActivation(string openId, out string statusCode)
        /// <summary>
        /// 激活帐户
        /// </summary>
        /// <param name="openId">唯一识别码</param>
        /// <param name="statusCode">返回状态码</param>
        /// <returns>用户实体</returns>
        public UserInfo AccountActivation(string openId, out string statusCode)
        {
            // 1.用户是否存在？
            UserInfo userInfo = null;
            // 用户没有找到状态
            statusCode = StatusCode.UserNotFound.ToString();
            // 检查是否有效的合法的参数
            if (!String.IsNullOrEmpty(openId))
            {
                PiUserManager userManager = new PiUserManager(DBProvider);
                DataTable dataTable = userManager.GetDT(PiUserTable.FieldOpenId, openId, PiUserTable.FieldDeleteMark, 0);
                if (dataTable.Rows.Count == 1)
                {
                    PiUserEntity userEntity = new PiUserEntity(dataTable);
                    // 3.用户是否被锁定？
                    if (userEntity.Enabled == 0)
                    {
                        statusCode = StatusCode.UserLocked.ToString();
                        return userInfo;
                    }
                    if (userEntity.Enabled == 1)
                    {
                        // 2.用户是否已经被激活？
                        statusCode = StatusCode.UserIsActivate.ToString();
                        return userInfo;
                    }
                    if (userEntity.Enabled == -1)
                    {
                        // 4.成功激活用户
                        statusCode = StatusCode.OK.ToString();
                        userManager.SetProperty(PiUserTable.FieldId, userEntity.Id, PiUserTable.FieldEnabled, 1);
                        return userInfo;
                    }
                }
            }
            return userInfo;
        }
        #endregion

        #region private int ChangeOnLine(string id) 登录、重新登录、扮演时的在线状态进行更新
        /// <summary>
        /// 登录、重新登录、扮演时的在线状态进行更新
        /// </summary>
        /// <param name="id">当前用户</param>
        /// <returns>是否在线</returns>
        private int ChangeOnLine(string id)
        {
            int returnValue = 0;
            // 是自己在线，然后重新登录为别人时，需要把自己注销掉
            if (UserInfo != null && !string.IsNullOrEmpty(UserInfo.Id))
            {
                if (!string.IsNullOrEmpty(UserInfo.OpenId) && !UserInfo.Id.Equals(id))
                {
                    // 要设置为下线状态，这里要判断游客状态
                    returnValue += this.OnExit(UserInfo.Id);
                }
            }
            // 用户在线
            returnValue += this.OnLine(id);

            return returnValue;
        }
        #endregion

        #region public UserInfo Impersonation(string id) 扮演用户
        /// <summary>
        /// 扮演用户
        /// </summary>
        /// <param name="id">用户主键</param>
        /// <returns>用户类</returns>
        public UserInfo Impersonation(string id, out string statusCode)
        {
            UserInfo userInfo = null;
            // 获得登录信息
            DataTable dataTableLogOn = this.GetDTById(id);
            PiUserEntity userEntity = new PiUserEntity();
            userEntity.GetFrom(dataTableLogOn);
            // 只允许登录一次，需要检查是否自己重新登录了，或者自己扮演自己了
            if (!UserInfo.Id.Equals(id))
            {
                if (SystemInfo.CheckOnLine)
                {
                    if (userEntity.UserOnLine > 0)
                    {
                        statusCode = StatusCode.ErrorOnLine.ToString();
                        return userInfo;
                    }
                }
            }
            userInfo = this.ConvertToUserInfo(userEntity);
            if (userEntity.IsStaff.Equals("1"))
            {
                // 获得员工的信息
                PiStaffEntity staffEntity = new PiStaffEntity();
                PiStaffManager staffManager = new PiStaffManager(DBProvider, UserInfo);
                DataTable dataTableStaff = staffManager.GetDTById(id);
                staffEntity.GetFrom(dataTableStaff);
                userInfo = staffManager.ConvertToUserInfo(staffEntity, userInfo);
            }
            statusCode = StatusCode.OK.ToString();
            // 登录、重新登录、扮演时的在线状态进行更新
            this.ChangeOnLine(id);
            return userInfo;
        }
        #endregion       

        public DataTable GetDTByIds(string[] userIds)
        {
            string sqlQuery = " SELECT " + PiUserTable.TableName + ".* "
                            + "        , ( SELECT " + PiRoleTable.FieldRealName
                                        + "  FROM " + PiRoleTable.TableName
                                        + " WHERE " + PiRoleTable.FieldId + " = " + PiUserTable.TableName + "." + PiUserTable.FieldRoleId + ") AS RoleName "
                            + "   FROM " + PiUserTable.TableName;
            // 是否需要过滤数据，要考虑安全性
            //if (userIds != null && userIds.Length > 0)
            //{
            sqlQuery += " WHERE Id IN (" + BusinessLogic.ObjectsToList(userIds) + ")";
            //}
            sqlQuery += " ORDER BY " + PiUserTable.FieldSortCode;
            return DBProvider.Fill(sqlQuery);
        }

        #region private int ResetVisitInfo(string id) 重置访问情况
        /// <summary>
        /// 重置访问情况
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>影响行数</returns>
        private int ResetVisitInfo(string id)
        {
            SQLBuilder sqlBuilder = new SQLBuilder(DBProvider);
            sqlBuilder.BeginUpdate(PiUserTable.TableName);
            sqlBuilder.SetNull(PiUserTable.FieldFirstVisit);
            sqlBuilder.SetNull(PiUserTable.FieldPreviousVisit);
            sqlBuilder.SetNull(PiUserTable.FieldLastVisit);
            sqlBuilder.SetValue(PiUserTable.FieldLogOnCount, 0);
            sqlBuilder.SetWhere(PiUserTable.FieldId, id);
            return sqlBuilder.EndUpdate();
        }
        #endregion

        #region public int ResetVisitInfo(string[] ids) 重置
        /// <summary>
        /// 重置
        /// </summary>
        /// <param name="ids">主键数组</param>
        /// <returns>影响行数</returns>
        public int ResetVisitInfo(string[] ids)
        {
            int returnValue = 0;
            for (int i = 0; i < ids.Length; i++)
            {
                if (ids[i].Length > 0)
                {
                    returnValue += this.ResetVisitInfo(ids[i]);
                }
            }
            return returnValue;
        }
        #endregion

        #region private int ResetData() 重置数据
        /// <summary>
        /// 重置数据
        /// </summary>
        /// <returns>影响行数</returns>
        private int ResetData()
        {
            // 删除不存在的数据，进行数据同步
            int returnValue = 0;
            string sqlQuery = " DELETE FROM " + PiUserTable.TableName
                            + " WHERE Id NOT IN (SELECT Id FROM " + PiStaffTable.TableName + ") ";
            returnValue += DBProvider.ExecuteNonQuery(sqlQuery);
            // 更新排序顺序情况
            sqlQuery = " UPDATE " + PiUserTable.TableName
                     + " SET SortCode = " + PiStaffTable.TableName + "." + PiStaffTable.FieldSortCode
                     + " FROM " + PiStaffTable.TableName
                     + " WHERE " + PiUserTable.TableName + "." + PiUserTable.FieldId + " = " + PiStaffTable.TableName + "." + PiStaffTable.FieldId;
            returnValue += DBProvider.ExecuteNonQuery(sqlQuery);
            return returnValue;
        }
        #endregion

        #region private int ResetVisitInfo() 重置访问情况
        /// <summary>
        /// 重置访问情况
        /// </summary>
        /// <returns>影响行数</returns>
        private int ResetVisitInfo()
        {
            int returnValue = 0;
            SQLBuilder sqlBuilder = new SQLBuilder(DBProvider);
            sqlBuilder.BeginUpdate(PiUserTable.TableName);
            sqlBuilder.SetNull(PiUserTable.FieldFirstVisit);
            sqlBuilder.SetNull(PiUserTable.FieldPreviousVisit);
            sqlBuilder.SetNull(PiUserTable.FieldLastVisit);
            sqlBuilder.SetValue(PiUserTable.FieldLogOnCount, 0);
            returnValue = sqlBuilder.EndUpdate();
            return returnValue;
        }
        #endregion

        #region public int Reset() 重新设置数据
        /// <summary>
        /// 重新设置数据
        /// </summary>
        /// <returns>影响行数</returns>
        public int Reset()
        {
            int returnValue = 0;
            returnValue += this.ResetData();
            returnValue += this.ResetVisitInfo();
            return returnValue;
        }
        #endregion

        #region public int CheckUserStaff()
        /// <summary>
        /// 用户已经被删除的员工的UserId设置为Null，说白了，是需要整理数据
        /// </summary>
        /// <returns>影响行数</returns>
        public int CheckUserStaff()
        {
            string sqlQuery = " UPDATE Base_Staff SET UserId = null WHERE UserId NOT IN ( SELECT Id FROM BASE_USER WHERE DeleteMark = 0 ) ";
            return DBProvider.ExecuteNonQuery(sqlQuery);
        }
        #endregion

        #region public string GetCount() 获取用户数
        /// <summary>
        /// 获取用户数
        /// </summary>
        public string GetCount()
        {
            string sqlQuery = " SELECT COUNT(Id) AS UserCount "
                            + "   FROM " + this.CurrentTableName
                            + "  WHERE Enabled = 1";
            return DBProvider.ExecuteScalar(sqlQuery).ToString();
        }

        /// <summary>
        /// 获取在线人数
        /// </summary>
        public string GetOnLineCount()
        {
            string sqlQuery = " SELECT COUNT(Id) AS UserCount "
                            + "   FROM " + this.CurrentTableName
                            + "  WHERE Enabled = 1 AND UserOnLine = 1";
            return DBProvider.ExecuteScalar(sqlQuery).ToString();
        }

        public string GetLogOnCount(int days)
        {
            string sqlQuery = " SELECT COUNT(Id) AS UserCount "
                            + "   FROM " + this.CurrentTableName
                            + "  WHERE Enabled = 1 AND (DATEADD(d, " + days.ToString() + ", " + PiUserTable.FieldLastVisit + ") > " + DBProvider.GetDBNow() + ")";
            return DBProvider.ExecuteScalar(sqlQuery).ToString();
        }

        public string GetRegistrationCount(int days)
        {
            string sqlQuery = " SELECT COUNT(Id) AS UserCount "
                            + "   FROM " + this.CurrentTableName
                            + "  WHERE Enabled = 1 AND (DATEADD(d, " + days.ToString() + ", " + PiUserTable.FieldCreateOn + ") > " + DBProvider.GetDBNow() + ")";
            return DBProvider.ExecuteScalar(sqlQuery).ToString();
        }
        #endregion

        #region public override int BatchSave(DataTable dataTable) 批量保存
        /// <summary>
        /// 批量保存
        /// </summary>
        /// <param name="dataTable">数据表</param>
        /// <returns>影响行数</returns>
        public override int BatchSave(DataTable dataTable)
        {
            int returnValue = 0;
            PiUserEntity userEntity = new PiUserEntity();
            foreach (DataRow dataRow in dataTable.Rows)
            {
                // 删除状态
                if (dataRow.RowState == DataRowState.Deleted)
                {
                    string id = dataRow[PiUserTable.FieldId, DataRowVersion.Original].ToString();
                    if (id.Length > 0)
                    {
                        returnValue += this.Delete(id);
                    }
                }
                // 被修改过
                if (dataRow.RowState == DataRowState.Modified)
                {
                    string id = dataRow[PiUserTable.FieldId, DataRowVersion.Original].ToString();
                    if (!String.IsNullOrEmpty(id))
                    {
                        userEntity.GetFrom(dataRow);
                        returnValue += this.UpdateEntity(userEntity);
                    }
                }
                // 添加状态
                if (dataRow.RowState == DataRowState.Added)
                {
                    userEntity.GetFrom(dataRow);
                    returnValue += BusinessLogic.ConvertToInt(this.AddEntity(userEntity)) > 0 ? 1 : 0;
                }
                if (dataRow.RowState == DataRowState.Unchanged)
                {
                    continue;
                }
                if (dataRow.RowState == DataRowState.Detached)
                {
                    continue;
                }
            }
            return returnValue;
        }
        #endregion

        public DataTable Search(string search = null, string[] roleIds = null, bool? enabled = true, string auditStates = null)
        {
            return Search(string.Empty, search, roleIds, enabled, auditStates);
        }

        public DataTable Search(string permissionScopeItemCode, string search, string[] roleIds, bool? enabled, string auditStates)
        {
            search = BusinessLogic.GetSearchString(search);
            string sqlQuery = " SELECT " + PiUserTable.TableName + ".* "
                            + "," + PiRoleTable.TableName + "." + PiRoleTable.FieldRealName + " AS RoleName "
                            + " FROM " + PiUserTable.TableName
                            + "      LEFT OUTER JOIN " + PiRoleTable.TableName
                            + "      ON " + PiUserTable.TableName + "." + PiUserTable.FieldRoleId + " = " + PiRoleTable.TableName + "." + PiRoleTable.FieldId
                // 被删除的排出在外比较好一些
                            + " WHERE " + PiUserTable.TableName + "." + PiUserTable.FieldDeleteMark + " = 0 "
                            + " AND " + PiUserTable.TableName + "." + PiUserTable.FieldIsVisible + " = 1 ";
            if (!String.IsNullOrEmpty(search))
            {
                sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldUserName + " LIKE '" + search + "'"
                            + " OR " + PiUserTable.TableName + "." + PiUserTable.FieldCode + " LIKE '" + search + "'"
                            + " OR " + PiUserTable.TableName + "." + PiUserTable.FieldRealName + " LIKE '" + search + "'"
                            + " OR " + PiUserTable.TableName + "." + PiUserTable.FieldDepartmentName + " LIKE '" + search + "'"
                            + " OR " + PiUserTable.TableName + "." + PiUserTable.FieldDescription + " LIKE '" + search + "')";
            }
            if (!String.IsNullOrEmpty(auditStates))
            {
                sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldAuditStatus + " = '" + auditStates + "')";
            }
            if (enabled != null)
            {
                sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldEnabled + " = " + ((bool)enabled ? 1 : 0) + ")";
            }
            if ((roleIds != null) && (roleIds.Length > 0))
            {
                string roles = BusinessLogic.ArrayToList(roleIds, "'");
                sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldRoleId + " IN (" + roles + ") ";
                sqlQuery += "      OR " + PiUserTable.TableName + "." + PiUserTable.FieldId + " IN (" + "SELECT " + PiUserRoleTable.FieldUserId + " FROM " + PiUserRoleTable.TableName + " WHERE " + PiUserRoleTable.FieldRoleId + " IN (" + roles + ")" + "))";
            }

            // 是否过滤用户， 获得组织机构列表， 这里需要一个按用户过滤得功能
            if ((!UserInfo.IsAdministrator) && (SystemInfo.EnableUserAuthorizationScope))
            {
                // string permissionScopeItemCode = "Resource.ManagePermission";
                PiPermissionItemManager permissionItemManager = new PiPermissionItemManager(this.DBProvider, this.UserInfo);
                string permissionScopeItemId = permissionItemManager.GetId(PiPermissionItemTable.FieldCode, permissionScopeItemCode);
                if (!string.IsNullOrEmpty(permissionScopeItemId))
                {
                    // 从小到大的顺序进行显示，防止错误发生
                    UserScopeManager userPermissionScopeManager = new UserScopeManager(this.DBProvider, this.UserInfo);
                    string[] organizeIds = userPermissionScopeManager.GetOrganizeIds(this.UserInfo.Id, permissionScopeItemId);

                    // 没有任何数据权限
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.None).ToString()))
                    {
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldId + " = NULL ) ";
                    }
                    // 按详细设定的数据
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.Detail).ToString()))
                    {
                        PiPermissionScopeManager permissionScopeManager = new PiPermissionScopeManager(DBProvider, UserInfo);
                        string[] userIds = permissionScopeManager.GetUserIds(UserInfo.Id, permissionScopeItemCode);
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldId + " IN (" + BusinessLogic.ObjectsToList(userIds) + ")) ";
                    }
                    // 自己的数据，仅本人
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.User).ToString()))
                    {
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldId + " = " + this.UserInfo.Id + ") ";
                    }
                    // 用户所在工作组数据
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.UserWorkgroup).ToString()))
                    {
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldWorkgroupId + " = " + this.UserInfo.WorkgroupId + ") ";
                    }
                    // 用户所在部门数据
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.UserDepartment).ToString()))
                    {
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldDepartmentId + " = " + this.UserInfo.DepartmentId + ") ";
                    }
                    // 用户所在公司数据
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.UserCompany).ToString()))
                    {
                        sqlQuery += " AND (" + PiUserTable.TableName + "." + PiUserTable.FieldCompanyId + " = " + this.UserInfo.CompanyId + ") ";
                    }
                    // 全部数据，这里就不用设置过滤条件了
                    if (BusinessLogic.Exists(organizeIds, ((int)PermissionScope.All).ToString()))
                    {
                    }
                }
            }
            sqlQuery += " ORDER BY " + PiUserTable.TableName + "." + PiUserTable.FieldSortCode;
            return DBProvider.Fill(sqlQuery);
        }        
    }
}
